/*
 * # iohao.com . 渔民小镇
 * Copyright (C) 2021 - 2022 double joker （262610965@qq.com） . All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.iohao.game.simulation.client.socket;

import com.iohao.game.action.skeleton.core.DataCodecKit;
import com.iohao.game.bolt.broker.client.external.bootstrap.message.ExternalMessage;
import com.iohao.game.common.kit.StrKit;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import org.noear.solon.core.message.Session;

import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;

/**
 * @author 渔民小镇
 * @date 2022-11-01
 */
@Slf4j
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class IoGameClientSocket {
    WebSocketClient webSocketClient;
    Session session;

    private IoGameClientSocket() {
    }

    public static IoGameClientSocket create(String wsUrl, Session session) {
        IoGameClientSocket clientSocket = new IoGameClientSocket();
        clientSocket.session = session;

        if (StrKit.isEmpty(wsUrl)) {
            wsUrl = "ws://127.0.0.1:10100/websocket";
        }

        try {
            clientSocket.connect(wsUrl);
        } catch (URISyntaxException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }

        return clientSocket;
    }

    /**
     * 将消息发送到游戏对外服
     *
     * @param clientExternalMessage clientExternalMessage
     */
    public void send(ClientExternalMessage clientExternalMessage) {

        // 将 ClientExternalMessage 转为 ExternalMessage
        ExternalMessage externalMessage = clientExternalMessage.toExternalMessage();

        byte[] externalMessageBytes = DataCodecKit.encode(externalMessage);

        // 将消息发送到 ioGame 的游戏对外服
        this.webSocketClient.send(externalMessageBytes);
    }

    private void connect(String wsUrl) throws URISyntaxException {


        this.webSocketClient = new WebSocketClient(new URI(wsUrl), new Draft_6455()) {
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                log.info("连接 ioGame 游戏对外服 {}", wsUrl);
            }

            @Override
            public void onMessage(String s) {
            }

            @Override
            public void onClose(int i, String s, boolean b) {
            }

            @Override
            public void onError(Exception e) {
            }

            @Override
            public void onMessage(ByteBuffer byteBuffer) {
                // 接收游戏对外服返回的消息
                byte[] dataContent = byteBuffer.array();

                ExternalMessage externalMessage = DataCodecKit.decode(dataContent, ExternalMessage.class);

                // 将 ExternalMessage 转为 ClientExternalMessage
                ClientExternalMessage clientExternalMessage = ClientExternalMessage.convert(externalMessage);

                // 将消息推送到 web 前端
                String json = clientExternalMessage.toJson();
                log.info("给模拟客户端发送消息\n {}", json);
                IoGameClientSocket.this.session.send(json);
            }
        };

        // 开始连接服务器
        webSocketClient.connect();
    }


}
